using System;
using System.Collections;
using ScenarioFramework.WorkflowEngine.DataModel;

namespace ScenarioFramework.WorkflowEngine.DataModel.WorkflowDataTypes
{
	//*********************************************************************
	//
	// XmlEnumerationValues Class
	//
	// The XmlEnumerationValues class represents a collection base of XmDataTypeValue
	// Its imports methods from WAPI.XmlObjectSet like get set and add
	// XmlEnumerationValues Has no fields
	//
	//*********************************************************************

	public class XMLEnumerationValues : bOSdotNET.XML.Data.XMLObjectSet
	{
		public const string MAIN_NODE	= "EnumerationValues";

		public const string TYPE_ATTRIBUTE = "Type";

		public const string ENUMERATION_TYPE="Enumeration";
		public const string RANGE_TYPE="Range";

		private string sType = string.Empty;

		/** CONSTRUCTOR Empty **/
		public XMLEnumerationValues()
		{
			this.Init();
		}

		/** CONSTRUCTOR Width xml parsering**/
		public XMLEnumerationValues(System.Xml.XmlNode nodeList)
		{
			this.Parse (nodeList);
		}

		/** INSTANCE METHODS **/

		/** Inizialize Method **/
		override public void Init()
		{
			this.RemoveAll();
		}

		public string Type 
		{
			get { return sType;}
			set { sType = value;}
		}

		override public void Parse(System.Xml.XmlNode nodeList)
		{
			this.Init();

			System.Xml.XmlNode node;

			/** find the attributes situated on the root tag **/
			for ( int i=0; i<nodeList.Attributes.Count; i++)
			{
				node= nodeList.Attributes.Item(i);

				switch (node.Name)
				{
					case XMLEnumerationValues.TYPE_ATTRIBUTE:
						sType = node.InnerText;
						break;
				}
			}

			for ( int i=0; i<nodeList.ChildNodes.Count;i++)
			{
				node = nodeList.ChildNodes[i];

				switch ( node.Name) 
				{
					case XMLDataTypeValue.MAIN_NODE:
						this.Add ( new XMLDataTypeValue(node));
						break;
				}
			}
		}

		override public bOSdotNET.XML.XMLNode GetXMLNode()
		{
			bOSdotNET.XML.XMLNode xmlNode = new bOSdotNET.XML.XMLNode(XMLEnumerationValues.MAIN_NODE);

			xmlNode.AddAttribute ( new bOSdotNET.XML.XMLAttribute ( XMLEnumerationValues.TYPE_ATTRIBUTE, sType) );

			for ( int i=0; i<this.Count;i++)
			{
				xmlNode.AddNode ( this[i].GetXMLNode() );
			}

			return xmlNode;
		}

		public XMLDataTypeValue GetValue(string sKey)
		{
			XMLDataTypeValue dtValue = null;
			for ( int i=0; i<this.List.Count;i++)
			{
				dtValue = (XMLDataTypeValue)this.List[i];

				if ( dtValue.Key == sKey )
				{
					return dtValue;
				}
			}

			return dtValue;
		}

		/** SORTING  FIELDS **/

		public enum SortFields 
		{
			Key,
			Value
		}

		/** SORTING METHODS **/


		public void Sort(SortFields sortField, bool isAscending) 
		{
			switch (sortField) 
			{
				case SortFields.Key:
					InnerList.Sort(new KeyComparer());
					break;
				
				case SortFields.Value:
					InnerList.Sort(new ValueComparer());
					break;
			}
			if (!isAscending) InnerList.Reverse();
		}


		private sealed class KeyComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLDataTypeValue first = (XMLDataTypeValue) x;
				XMLDataTypeValue second = (XMLDataTypeValue) y;
				return first.Key.CompareTo(second.Key);
			}
		}


		private sealed class ValueComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLDataTypeValue first = (XMLDataTypeValue) x;
				XMLDataTypeValue second = (XMLDataTypeValue) y;
				return first.Value.CompareTo(second.Value);
			}
		}
	}
}
